/**
  ******************************************************************************
  * @file    bsp_timer_encoder.c
  * @author  fire
  * @version V1.0
  * @date    2024-xx-xx
  * @brief   EC11编码器模块
  ******************************************************************************
  * @attention
  *
  * 实验平台:野火 F103 STM32 开发板 
  * 论坛    :http://www.firebbs.cn
  * 淘宝    :https://fire-stm32.taobao.com
  *
  ******************************************************************************
  */ 
#include "timer/bsp_timer_encoder.h"

uint8_t laststate,nowstate = 1;     //编码器按键未按下默认高电平
uint8_t key_temp = 0;               //缓存编码器按键标志位
uint8_t key_flag = 0;               //编码器按键标志位
uint8_t dirction_flag = 0;          //方向标志位
uint8_t encoder_flag = 0;           //编码器标志位
uint16_t encoder_task_time;         //编码器任务计时计数值
uint16_t key_task_time;             //编码器按键任务计时计数值


/**
  * @brief  编码器的GPIO配置
  * @param  无
  * @retval 无
  */
static void Encoder_GPIO_Config(void)
{
    GPIO_InitTypeDef gpio_initstruct;
    /* 使能GPIO时钟 */
    ENCODER_RCC_CLK_ENABLE(ENCODER_RCC_CLK, ENABLE);

    /* 初始化GPIO */
    gpio_initstruct.GPIO_Mode = GPIO_Mode_IPU;
    gpio_initstruct.GPIO_Pin = ENCODER_A_GPIO_PIN;
    gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(ENCODER_A_GPIO_PORT, &gpio_initstruct);
    
    gpio_initstruct.GPIO_Pin = ENCODER_B_GPIO_PIN;
    GPIO_Init(ENCODER_B_GPIO_PORT, &gpio_initstruct);
    
    gpio_initstruct.GPIO_Pin = ENCODER_KEY_GPIO_PIN ;
    GPIO_Init(ENCODER_KEY_GPIO_PORT, &gpio_initstruct);
}

/**
  * @brief  TIM编码器接口模式配置
  * @param  无
  * @retval 无
  */
static void TIMX_Encoder_Config(void)
{
    TIM_TimeBaseInitTypeDef tim_base_initstruct;
    TIM_ICInitTypeDef tim_ic_initstruct;

    /* 使能TIM_ENCODER时钟 */
    TIM_ENCODER_RCC_CLK_ENABLE(TIM_ENCODER_RCC_CLK, ENABLE);

    /* =============================配置TIM_ENCODER时基单元============================ */
    /* 初始化TIM_ENCODER */
    tim_base_initstruct.TIM_ClockDivision = TIM_CKD_DIV1;
    tim_base_initstruct.TIM_CounterMode = TIM_CounterMode_Up;
    tim_base_initstruct.TIM_Period = 65536 - 1; /* ARR */
    tim_base_initstruct.TIM_Prescaler = 1 - 1;  /* PSC */
    tim_base_initstruct.TIM_RepetitionCounter = 0;

    TIM_TimeBaseInit(TIM_ENCODER, &tim_base_initstruct);

    /* =============================配置TIM_ENCODER输入捕获单元========================== */
    TIM_ICStructInit(&tim_ic_initstruct);   /* 结构体赋初值 */
    tim_ic_initstruct.TIM_Channel = ENCODER_A_CHANNEL | ENCODER_B_CHANNEL;
    tim_ic_initstruct.TIM_ICFilter = 0;

    TIM_ICInit(TIM_ENCODER, &tim_ic_initstruct);
    
    /* 配置TIM编码器接口 */
    TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);

    /* 使能TIMX */
    TIM_Cmd(TIM_ENCODER, ENABLE);
}

/**
  * @brief  获取编码器转值
  * @param  无
  * @retval 无
  */
void Encoder_Get_Val(float *cycle_count)
{
    int16_t temp;
    /* 获取当前计数值 */
    temp = TIM_ENCODER->CNT;

    /* 圈数累加 */
    *cycle_count += (float)temp / 80;

    if(temp == 0)   //静止
    {
        dirction_flag = STILLNESS;
    }
    else if(temp >= 0)  //正方向转
        {
        dirction_flag = POSITIVE_DIRECTION;
    }
    else if(temp <= 0)  //反方向转
        {
        dirction_flag = REVERSE_DIRECTION;
    }
    
    /* 清零CNT */
    TIM_ENCODER->CNT = 0;
}

/**
 * @brief  定时器中按键扫描
 * @param  无
 * @retval 无
 */
void Key_Scan_Loop(void)
{			
    laststate = nowstate;
    nowstate = GPIO_ReadInputDataBit(ENCODER_KEY_GPIO_PORT,ENCODER_KEY_GPIO_PIN);

    if(laststate==1 && nowstate==0) //检测按键按下
    {
        key_temp = PRESS;
    }
    else if(laststate==0 && nowstate==1)    //检测按键松开
    {
        key_temp = LOOSEN;
    }
        key_flag = key_temp;
        key_temp = 0;
}

/**
  * @brief  编码器GPIO初始化，TIM使用编码器接口模式
  * @param  无
  * @retval 无
  */
void TIMX_Encoder_Init(void)
{
    Encoder_GPIO_Config();
    TIMX_Encoder_Config();
}

/*********************************************END OF FILE**********************/
